/*
 * Class NPC
 *
 * Version 1.0
 *	
 * Monday, August 18, 2008
 *
 * Created by Palidino76
 */

package net.com.hydroPK.npcs;

import net.com.hydroPK.Engine;
import net.com.hydroPK.Server;
import net.com.hydroPK.model.Player;
import net.com.hydroPK.npcs.combat.NpcCombat;
import net.com.hydroPK.npcs.combat.VersusNpc;
import net.com.hydroPK.util.Misc;

public class NPC {
	public int followPlayer = 0;

    /**
     * Stray dog variables
     */
    public int dogBossy;
    public boolean followingBossy;
    /**
     * Killing count 1v1 at NPCs
     */
    public int killingCount;
    public boolean playerTele;
    public int[] kalphiteMonsters = {
            1153, 1154, 1155, 1156, 1157, 1158, 1160
    };
    public int[] fightCaveNpcs = {
            2734, 2735, 2736, 2737, 2738, 2739, 2740, 2741, 2742, 2743, 2744
    };
    public int[] someNpcs = {
            2745, 4284
    };
    public boolean spawnedHealers;
    public int projectileShowDelay = -1;
    public int[] largeNpcs = {
            50, 1158, 1160, 3847, 6222, 6203, 6260, 6247,3200,5666,
    };
    /**
     * Summoning
     */
    public int[] summoningMonsters = {
            6829, 7343, 6811, 6825, 6994, 6804, 6879, 6881, 6885
    };
    /**
     * 1 V 1
     */
    public int spawnedFor;
    /**
     * Drop calculator (Calculates who to drop to)
     */
    public int killing[] = new int[Engine.maxPlayers];
    public int startKilling;
    public int getKiller(int NPCID) {
        int Killer = 0;
        int Count = 0;
        for (int i = 1; i <= Engine.maxPlayers; i++) {
            if (Engine.players[i] == null)
                continue;
            if (Killer == 0) {
                Killer = i;
                Count = 1;
            } else {
                if (Engine.npcs[NPCID].killing[i] > Engine.npcs[NPCID].killing[Killer]) {
                    Killer = i;
                    Count = 1;
                } else if (Engine.npcs[NPCID].killing[i] == Engine.npcs[NPCID].killing[Killer]) {
                    Count++;
                }
            }
        }
        if ((Count > 1)
                && (Engine.npcs[NPCID].killing[Engine.npcs[NPCID].startKilling] ==
                Engine.npcs[NPCID].killing[Killer])) {
            Killer = Engine.npcs[NPCID].startKilling;
        }
        return Killer;
    }
    /**
     * An array with NPC ids of npcs which are animated armours.
     */
    public int[] animatedArmours = {
            4284
    };
    /**
     * An array with NPC ids of npcs which check on combat levels for agression
     */
    public int[] combatNpcs = {
            6625, 1153, 1154, 1156, 6998, 6999, 6729, 6625,5666
    };
    /**
     * An array with NPC ids of npcs which heal themself.
     */
    public int[] healingNpcs = {
            6729, 6625, 6691
    };
    public int walkX, walkY;
    public boolean revenantRangedAttk;
    public int size;
    /**
     * The delay for gfx appearing on KQ.
     */
    public int changeAnimDelay;
    public int kqGfxDelay = -1, kqDeathDelay = -1, kqDeathDelay1 = -1;
    public int brokenArmour;
    public boolean kalphRanged;
    public int[] agressionNpcs = {
            50, 2745, 6203, 907, 6222, 6220, 1158, 1160, 1153, 1154, 1155, 1156, 1157,
            5363, 53, 55, 2744, 2743, 6260, 6998, 6999, 7770, 7771, 134,
            2734, 2735, 107, 5902, 3847, 6729, 6691, 6247, 2739, 2740, 2745, 2746,
            5253, 5417, 5421, 5420, 8133,3200,5666,9000,9001,9002,7161
    };
    /**
     * NPC vs NPC variables
     */
    public int[] npcMagics = {
            2253, 6257,3200,1885
    };
    public int damageDelay = -1;
    public int attackDelay;
    public boolean attackingNpc;
    public int npcEnemy;
    /**
     * Array with demon types npcs.
     */
    public int[] demonTypes = {
            82, 83, 84, 6203, 6204, 6208, 9000, 9001, 9002
    };
    public boolean appendDrop, appendDrop1;
    /**
     * Range/mage hit delay.
     */
    public boolean mageType, rangeType;
    public int rockAppear = -1;
    public int farCastDelay = -1;
    /**
     * A simple array with npc ids in it which are mage npcs.
     */
    public int[] mageNpcs = {
            50, 2743, 2744, 2745, 5363, 55, 53, 907, 6222, 6220, 1158, 1160, 6203, 6208, 6223, 6225, 6227, 6998, 6999, 5902, 3847, 6729, 6625, 6691,
            6250, 2739, 2740, 2745, 6252, 1472, 6263, 6265, 8133, 2025, 9000, 9001, 9002, 2028,3200
    };
    /**
     * Defence
     */
    public int meleeDef;
    /**
     * Death delay
     */
    public int deathDelay;
    /**
     * Player index (enemy) (combat)
     */
    public int playerIndex;
    /**
     * Attacking Player.
     */
    public boolean underAttack;
    /**
     * Atk delay
     */
    public int atkDelay;
    /**
     * Used to make 1v1.
     */
    public int battleCDelay;
    public int battleCount;
    /**
     * The position this NPC is stored in the npc array in the Engine class.
     */
    public int npcId = -1;
    /**
     * The NPC's id, such as 50 for king black dragon.
     */
    public int npcType = 0;
    /**
     * The name of this NPC.
     */
    public String name = "";
    /**
     * If it should hit 0 HP, how long it should take to respawn.
     */
    public int respawnDelay = 30;
    /**
     * Its combat level, used for calculating its accuracy and defence.
     */
    public int combatLevel = 0;
    /**
     * Max hitpoints it can have.
     */
    public int maxHP = 0;
    /**
     * The basic max hit it can have, with an attack method you  can get more specific.
     */
    public int maxHit = 0;
    /**
     * Attack type, 0 for melee, 1 for range, 2 for magic.
     */
    public int atkType = 0;
    /**
     * The weakness, same setup as atkType.
     */
    public int weakness = 0;
    /**
     * The current HP this NPC has.
     */
    public int currentHP = 0;
    /**
     * The direction this NPC is moving in.
     */
    public int direction = -1;
    /**
     * The height level its at.
     */
    public int heightLevel = 0;
    /**
     * Request for updating facing.
     */
    public boolean faceToUpdateReq = false;
    public int faceToRequest = -1;
    /**
     * If the NPC is dead or not.
     */
    public boolean isDead = false;
    /**
     * If the death emote has been requested, move on to the next part of the death process.
     */
    public boolean deadEmoteDone = false;
    /**
     * Hide the NPC until it is ready to respawn.
     */
    public boolean hiddenNPC = false;
    /**
     * Absolute positioning.
     */
    public int absX = 0, absY = 0;
    /**
     * If false, the NPC will not respawn if it dies.
     */
    public boolean needsRespawn = false;
    /**
     * If set to true, this NPC will randomly walk around.
     */
    public boolean randomWalk = true;
    /**
     * If an update is needed.
     */
    public boolean updateReq = false;
    /**
     * If the NPC should speak.
     */
    public boolean speakTextUpdateReq = false;
    public String speakText = "";
    /**
     * Hit requests.
     */
    public boolean hit1UpdateReq = false;
    public boolean hit2UpdateReq = false;
    public int hitDiff1 = 0;
    public int posionHit1 = 0;
    public int hitDiff2 = 0;
    public int posionHit2 = 0;
    /**
     * Animation request.
     */
    public boolean animUpdateReq = false;
    public int animRequest = 65535;
    public int animDelay = 0;
    /**
     * Graphic request.
     */
    public boolean gfxUpdateReq = false;
    public int gfxRequest = 65535;
    public int gfxDelay = 0;
    /**
     * Facing request.
     */
    public boolean faceCoordsUpdateReq = false;
    public int faceCoordsX = -1;
    public int faceCoordsY = -1;
    /**
     * The area this NPC can randomly walk around.
     */
    public int moveRangeX1 = 0;
    public int moveRangeY1 = 0;
    public int moveRangeX2 = 0;
    public int moveRangeY2 = 0;
    /**
     * What should be added onto the absolute positioning if this NPC moves.
     */
    public int moveX = 0;
    public int moveY = 0;
    /**
     * The original position the NPC spawned at.
     */
    public int makeX = 0;
    public int makeY = 0;
    /**
     * Delay before the NPC can attack again.
     */
    public int combatDelay = 0;

    /**
     * Constructs a new NPC class.
     *
     * @param type  The type of NPC.
     * @param index The position the NPC is at.
     */
    public NPC(int type, int index) {
        npcType = type;
        npcId = index;
        size = 0;
        for (int i = 0; i < killing.length; i++) {
            killing[i] = 0;
        }
    }

    /**
     * This method is called every 600 milliseconds.
     */
    public void process() {
        

	
	
	
	

	if (respawnDelay > 0 && isDead) {
            respawnDelay--;
        }
        if (npcType == 2745) {
            if (currentHP >= 1) {
                if (!spawnedHealers) {
                    if (currentHP <= 180) {
                        for (int i = 0; i < 3; i++)
                            Server.engine.newNPC(2746, 2400 + Misc.random(2), 5144 + Misc.random(2), heightLevel, 0, 0, 0, 0, false, spawnedFor);
                        spawnedHealers = true;
                    }
                }
            }
        }
        if (npcType == 2746) {
            if (currentHP >= 1) {
                for (int i = 0; i < 10000; i++) {
                    if (this == null || currentHP <= 0)
                        return;
                    if (Server.engine.npcs[i] == null)
                        continue;
                    if (Misc.random(20) == 5) {
                        if (Server.engine.npcs[i].npcType == 2745 && heightLevel == Server.engine.npcs[i].heightLevel) {
                            if (currentHP <= 0 || this == null || heightLevel != Server.engine.npcs[i].heightLevel)
                                return;
                            if (Server.engine.npcs[i].currentHP > 316) {
                                Server.engine.npcs[i].currentHP = 316;
                                return;
                            }
                            if (Server.engine.npcs[i].currentHP <= 315) {
                                Server.engine.npcs[i].requestGFX(444, 100);
                                Server.engine.npcs[i].currentHP += Misc.random(25);
                            }
                        }
                    }
                }
            }
        }
        if (projectileShowDelay > 0)
            projectileShowDelay--;
        if (projectileShowDelay == 0) {
            NpcCombat npcAttack1 = new NpcCombat(this);
            npcAttack1.createNPCProjectile();
        }
        if (changeAnimDelay > 0)
            changeAnimDelay--;
        if (damageDelay > 0)
            damageDelay--;
        if (damageDelay == 0) {
            VersusNpc npcAttack = new VersusNpc(this);
            npcAttack.addDamageToNpcEvent();
        }
        if (kqGfxDelay > 0) {
            kqGfxDelay--;
        }
        if (kqGfxDelay == 0) {
            //absX++;
            //absY += 2;
            //heightLevel = 0;
            //npcType = 1161;
            Server.engine.rebuildNPCs();
            requestGFX(1055, 0);
            kqGfxDelay = -1;
        }
        if (kqDeathDelay > 0) {
            kqDeathDelay--;
        }
        if (kqDeathDelay == 0) {
            requestAnim(6242, 0);
            kqGfxDelay = 3;
            kqDeathDelay = -1;
        }
        if (attackDelay > 0) {
            attackDelay--;
        }
        if (attackDelay == 0 && attackingNpc) {
            VersusNpc versusNpc = new VersusNpc(this);
            versusNpc.appendMelee();
        }
        if (farCastDelay > 0) {
            farCastDelay--;
        }
        if (farCastDelay == 0) {
            NpcCombat npcCb2 = new NpcCombat(this);
            npcCb2.appendFarcastDamage();
        }
        if (rockAppear > 0) {
            rockAppear--;
        }
        if (rockAppear == 0) {
            NpcCombat npcCombat = new NpcCombat(this);
            npcCombat.appendRock();
        }
        if (deathDelay > 0) {
            deathDelay--;
        }
        if (currentHP <= 0 && !isDead) {
            isDead = true;
            deathDelay = 6;
        }
        if (isDead && deathDelay == 0) {
            appendNpcDrops();
            appendDeath();

        }
        if (combatDelay > 0) {
            combatDelay--;
	}

        

        if (battleCDelay > 0) {
            battleCDelay--;
        }
        if (battleCDelay == 0) {
            battleCount = 0;
            battleCDelay = -1;
        }
        if (atkDelay > 0) {
            atkDelay--;
        }
        if (underAttack) {
            NpcCombat npcCb = new NpcCombat(this);
            npcCb.appendAttackPlayer();
        }
        for (int s = 0; s < summoningMonsters.length; s++) {
            if (npcType == summoningMonsters[s]) {
                Player p = Server.engine.players[spawnedFor];
                if (p == null || this == null || Server.engine.npcs[spawnedFor] == null || p.disconnected[0]) {
                    return;
                }
                NpcCombat combat = new NpcCombat(this);
                if (!p.familiarDissMiss) {
                    if (Misc.getDistance(absX, absY, p.absX, p.absY) > 9 || p.callFamiliar) {
                        absX = p.absX - 1;
                        absY = p.absY;
                        heightLevel = p.heightLevel;
                        Server.engine.rebuildNPCs();
                        p.callFamiliar = false;
                    }
                    if (Misc.random(10) == 7)
                        requestText("Grr..");
                    combat.appendPlayerFollowing(p);
                    requestFaceCoords(p.absX, p.absY);
                    requestFaceTo(spawnedFor);
                } else if (p.familiarDissMiss || p == null || p.disconnected[0]) {
                    absX = 0;
                    absY = 0;
                    heightLevel = 0;
                    p.summonDrainDelay = -1;
                    Server.engine.npcs[spawnedFor] = null;
                    Server.engine.rebuildNPCs();
                    spawnedFor = 0;
                    p.summonedFamiliar = false;
                    p.familiarDissMiss = false;
                }
            }
        }
        for (int j = 0; j < healingNpcs.length; j++) {
            if (npcType == healingNpcs[j]) {
                if (currentHP <= getCurrentNpcHP()) {
                    if (Misc.random(10) == 5)
                        currentHP += Misc.random(20);
                }
            }
        }
        if (npcType == 7771) {
            if (brokenArmour == 0) {
                requestGFX(1629, 0);
                npcType = 7770;
                Server.engine.rebuildNPCs();
                brokenArmour = -1;
            }
        }

        for (int i = 0; i < 10000; i++) {
            if (Server.engine.npcs[i] == null)
                continue;
            VersusNpc versNpc = new VersusNpc(this);
            if (npcType == 158) {
                if (Server.engine.npcs[i].npcType == 158) {
                    if (npcEnemy > 0 || Server.engine.npcs[i].currentHP <= 0 || currentHP <= 0 || this == null || Server.engine.npcs[i] == null) {
                        versNpc.resetAttack();
                        return;
                    }
                    randomWalk = false;
                    npcEnemy = i;
                    attackingNpc = true;
                    Server.engine.npcs[i].randomWalk = false;
                }
            }
              if (npcType == 2270) 
	requestText("Steal from stalls to gain exp!");
            if (npcType == 3846) {
                if (Server.engine.npcs[i].npcType == 2253) {
                    if (npcEnemy > 0 || Server.engine.npcs[i].currentHP <= 0 || currentHP <= 0 || this == null || Server.engine.npcs[i] == null) {
                        versNpc.resetAttack();
                        return;
                    }
                    randomWalk = false;
                    npcEnemy = i;
                    attackingNpc = true;
                    Server.engine.npcs[i].randomWalk = false;
                }
            }
            if (npcType == 2253) {
                if (Server.engine.npcs[i].npcType == 3846) {
                    if (Misc.getDistance(absX, absY, Server.engine.npcs[i].absX, Server.engine.npcs[i].absY) <= 7) {
                        if (npcEnemy > 0 || Server.engine.npcs[i].currentHP <= 0 || currentHP <= 0 || this == null || Server.engine.npcs[i] == null) {
                            versNpc.resetAttack();
                            return;
                        }
                        randomWalk = false;
                        npcEnemy = i;
                        attackingNpc = true;
                        Server.engine.npcs[i].randomWalk = false;
                    }
                }
            }
            if (npcType == 6257) {
                if (Server.engine.npcs[i].npcType == 6212) {
                    if (Misc.getDistance(absX, absY, Server.engine.npcs[i].absX, Server.engine.npcs[i].absY) <= 10) {
                        if (npcEnemy > 0 || Server.engine.npcs[i].currentHP <= 0 || currentHP <= 0 || this == null || Server.engine.npcs[i] == null) {
                            versNpc.resetAttack();
                            return;
                        }
                        randomWalk = false;
                        npcEnemy = i;
                        attackingNpc = true;
                        Server.engine.npcs[i].randomWalk = false;
                    }
                }
            }
            if (npcType == 6210) {
                if (Server.engine.npcs[i].npcType == 6257) {
                    if (Misc.getDistance(absX, absY, Server.engine.npcs[i].absX, Server.engine.npcs[i].absY) <= 10) {
                        if (npcEnemy > 0 || Server.engine.npcs[i].currentHP <= 0 || currentHP <= 0 || this == null || Server.engine.npcs[i] == null) {
                            versNpc.resetAttack();
                            return;
                        }
                        randomWalk = false;
                        npcEnemy = i;
                        attackingNpc = true;
                        Server.engine.npcs[i].randomWalk = false;
                    }
                }
            }
        }
        for (int npc = 0; npc < someNpcs.length; npc++) {
            if (npcType == someNpcs[npc]) {
                Player player = Server.engine.players[spawnedFor];
                if (player == null || this == null) {
                    spawnedFor = 0;
                    underAttack = false;
                    return;
                }
                underAttack = true;
            }
        }
        for (Player p : Server.engine.players) {
            if (p != null && this != null) {
                if (Misc.getDistance(absX, absY, p.absX, p.absY) <= getDistance() && p.heightLevel == heightLevel) {
                    for (int i = 0; i < agressionNpcs.length; i++) {
                        if (npcType == agressionNpcs[i]) {
                            if (p == null || this == null || p.disconnected[0]) {
                                underAttack = false;
                                playerIndex = 0;
                                return;
                            }
                            if (currentHP >= 1 && p.skillLvl[3] >= 1) {
                                playerIndex = p.playerId;
                                for (int z = 0; z < combatNpcs.length; z++) {
                                    if (npcType == combatNpcs[z]) {
                                        if (!underAttack) {
                                            if (p.combatLevel <= getCombatCheck())
                                                underAttack = true;
                                            else
                                                underAttack = false;
                                        }
                                    } else {
                                        underAttack = true;
                                    }
                                }
                                randomWalk = false;
                            }
                        }
                    }
                }
            }
        }
        if (npcType == 925) {
          if (Misc.random(10) == 5) {
              requestText("Register at: www.hydroPK.tk");
          }
      }

    }

    public int nextKillStage(int npcType) {
        switch (npcType) {
            case 2026:
                return 2;
            case 2025:
                return 3;
            case 2027:
                return 4;
            case 2029:
                return 5;
            case 2028:
                return 6;
            case 2030:
                return 7; // Yay chest x]
        }
        return 0;
    }

    /**
     * Death system.
     */
    public void appendDeath() {
        if (deathDelay == 0 && isDead) {
            if (!npcsResetting) {

                if (npcType == 2736 || npcType == 2737) {
                    Engine.newNPC(2738, absX, absY, heightLevel, 0, 0, 0, 0, false, spawnedFor);
                    Engine.newNPC(2738, absX + 1, absY, heightLevel, 0, 0, 0, 0, false, spawnedFor);
                }
                if (npcType == 5421) {
                    Engine.newNPC(5420, absX, absY, heightLevel, 0, 0, 0, 0, false, 0);
                    needsRespawn = false;
                    deathDelay = -1;
                    return;
                }
                if (npcType == 1158 || npcType == 1161) {
                    absX = 3476;
                    absY = 9500;
                    Engine.newNPC(1160, absX, absY, 4, 0, 0, 0, 0, false, 0);
                    needsRespawn = false;
                    deathDelay = -1;
                }
                if (npcType == 2783 || npcType == 1615) {
                    killingCount = 0;
                }
                if (npcType == 5420) {
                    npcType = 5421;
                    Server.engine.rebuildNPCs();
                    respawnDelay = 200;
                    needsRespawn = true;
                    deathDelay = -1;
                }
                if (npcType == 1160) {
                    npcType = 1158;
                    absX = 3476;
                    absY = 9500;
                    heightLevel = 4;
                    respawnDelay = 50;
                    needsRespawn = true;
                    deathDelay = -1;
                    Server.engine.rebuildNPCs();
                }
            }
            deathDelay = -1;
        }
    }

    public boolean npcsResetting = false;

    /**
     * Npc drops items if player killed npc.
     */
    public void appendNpcDrops() {
        Player p = Engine.players[getKiller(npcId)];
        if (p == null) {
            playerIndex = 0;
            resetAttack();
            return;
        }
        Player s = Engine.players[spawnedFor];
        if (spawnedFor > 0) {
            if (s == null || spawnedFor == 0) {
                resetAttack();
                spawnedFor = 0;
                return;
            }
        }
        /** GODWARS KILLS **/
        if (npcType == 6223 || npcType == 6225 || npcType == 6227) {
            // Armadyl
            p.armadylKills++;
            if (p.armadylKills == 10) {
                p.message("You have reached 10 Armadyl kills, you can now enter the boss room.");
            }
            p.sendGodwarsInterface();
        }
        if (npcType == 6261 || npcType == 6263 || npcType == 6265) {
            // Bandos
            p.bandosKills++;
            if (p.bandosKills == 10) {
                p.message("You have reached 10 Bandos kills, you can now enter the boss room.");
            }
            p.sendGodwarsInterface();
        }
        if (npcType == 6248 || npcType == 6250) {
            // Saradomin
            p.saradominKills++;
            if (p.saradominKills == 10) {
                p.message("You have reached 10 Saradomin kills, you can now enter the boss room.");
            }
            p.sendGodwarsInterface();
        }
        if (npcType == 6204 || npcType == 6208) {
            // Zamorak
            p.zamorakKills++;
            if (p.zamorakKills == 10) {
                p.message("You have reached 10 Zamorak kills, you can now enter the boss room.");
            }
            p.sendGodwarsInterface();
        }



        /* BARROWS - TELEPORT INSTEAD OF DROP */
        if (npcType >= 2025 && npcType <= 2030) {
            // Barrows kills
            p.barrowsStage = nextKillStage(npcType);
            int stage[][] = p.barrowsCoords;
            int num = p.barrowsStage - 1;
            int killsLeft = 6 - num;
            p.sendBarrowsOverlay(num);
            p.teleportTo(stage[num][0], stage[num][1], 0, true);
            if (killsLeft != 0 && p.barrowsStage < 7) { // Chest
                p.sendNpcDialogue(0, 5488, "Magnus Gram", "Well done! On to the next stage!",
                        "You need to kill " + killsLeft + " more!");
            } else {
                p.sendNpcDialogue(0, 5488, "Magnus Gram", "Congratulations! You did it!",
                        "Now just open the chest for the reward!");
            }
        }


        switch (npcType) {

            case 5253:
                if (Misc.random(10) == 5)
                    Server.engine.items.createGroundItem(10581, 1, absX, absY, heightLevel, p.username);
                break;

            case 2745:
                Server.engine.playerItems.addItem(p, 6570, 1);
                p.getActionSender().sendMessage(s, "Congratulations, you've beaten Tztok-Jad.");
                p.requestAnim(862, 0);

                break;


            case 81:
                Engine.items.createGroundItem(526, 1, absX, absY, heightLevel, p.username);
                Engine.items.createGroundItem(1739, 1, absX, absY, heightLevel, p.username);
                Engine.items.createGroundItem(2132, 1, absX, absY, heightLevel, p.username);
                break;

            case 107:
                Engine.items.createGroundItem(5319, 1, absX, absY, heightLevel, p.username);
                break;


            case 2614:
                Engine.items.createGroundItem(6529, Misc.random(129), absX, absY, heightLevel, p.username);
                break;


            case 7770:
                Engine.items.createGroundItem(6529, 1000, absX, absY, heightLevel, p.username);
                Engine.items.createGroundItem(532, 1, absX, absY, heightLevel, p.username);
                break;

            case 4284:
                Engine.items.createGroundItem(1127, 1, absX, absY + 1, heightLevel, s.username);
                Engine.items.createGroundItem(1079, 1, absX, absY + 1, heightLevel, s.username);
                Engine.items.createGroundItem(1163, 1, absX, absY + 1, heightLevel, s.username);
                Engine.items.createGroundItem(8851, Misc.random(45), absX, absY + 1, heightLevel, s.username);
                break;
        }
        Engine.dropNPCItems(npcType, this, p); // Drops items from the file
        // - Devin/hydroPK
        p.attackNpc = 0;
        p.attackingNpc = false;
        playerIndex = 0;
    }

    /**
     * Request an animation for this NPC.
     *
     * @param animId The amination to perform.
     * @param animD  The delay before doing the animation.
     */
    public void requestAnim(int animId, int animD) {
        animRequest = animId;
        animDelay = animD;
        animUpdateReq = true;
        updateReq = true;
    }

    /**
     * Request text for this NPC.
     *
     * @param message The message to make the NPC say.
     */
    public void requestText(String message) {
        speakText = message;
        animUpdateReq = true;
        speakTextUpdateReq = true;
    }

    /**
     * Request an graphic for this NPC.
     *
     * @param gfxId The graphic to perform.
     * @param gfxD  The delay or height or the gfx depending on the value.
     */
    public void requestGFX(int gfxId, int gfxD) {
        if (gfxD == 100) {
            gfxD = 6553600;
        }
        gfxRequest = gfxId;
        gfxDelay = gfxD;
        gfxUpdateReq = true;
        updateReq = true;
    }

    /**
     * Request this NPC faces two coordinates.
     *
     * @param x The x coordinate to face.
     * @param y The y coordinate to face.
     */
    public void requestFaceCoords(int x, int y) {
        faceCoordsX = 2 * x + 1;
        faceCoordsY = 2 * y + 1;
        faceCoordsUpdateReq = true;
        updateReq = true;
    }

    /**
     * Request this NPC faces another NPC or player.
     *
     * @param faceId The target to face.
     */
    public void requestFaceTo(int faceId) {
        faceToRequest = faceId;
        faceToUpdateReq = true;
        updateReq = true;
    }

    /**
     * Resets attack of npc.
     */
    public void resetAttack() {
        battleCount = 0;
        underAttack = false;
    }

    /**
     * Switch jad attack types.
     *
     * @param mageType  the mage attack type.
     * @param rangeType the range attack type.
     */
    public void switchJadAttack(boolean rangeType, boolean mageType) {
        this.rangeType = rangeType;
        this.mageType = mageType;
    }

    /**
     * Switch corp attack types.
     *
     * @param mageType  the mage attack type.
     * @param rangeType the range attack type.
     */
    public void switchCorpAttack(boolean rangeType, boolean mageType) {
        this.rangeType = rangeType;
        this.mageType = mageType;
    }

    /**
     * Add damage to this NPC.
     *
     * @param damage To amount of damage.
     * @param posion 0 for normal damage, 1 for posion.
     */
    public void appendHit(int damage, int posion) {
        if (this == null)
            return;
        if (damage > currentHP) {
            damage = currentHP;
        }
        currentHP -= damage;
        NpcCombat npcCb1 = new NpcCombat(this);
        if (currentHP <= 0 && npcType != 1158) {
            requestAnim(npcCb1.getDeathAnim(), 0);
            currentHP = 0;
            deathDelay = 8;
            isDead = true;
        } else if (currentHP <= 0 && npcType == 1158) {
            currentHP = 0;
            deathDelay = 15;
            kqDeathDelay = 4;
            isDead = true;
        }
        if (!hit1UpdateReq) {
            hitDiff1 = damage;
            posionHit1 = posion;
            hit1UpdateReq = true;
        } else {
            hitDiff2 = damage;
            posionHit2 = posion;
            hit2UpdateReq = true;
        }
        updateReq = true;
    }

    /**
     * Add damage to this NPC.
     *
     * @param damage To amount of damage.
     * @param posion 0 for normal damage, 1 for posion.
     */
    public void append1Hit(int damage, int posion) {
        if (damage > currentHP) {
            damage = currentHP;
        }
        currentHP -= damage;
        NpcCombat npcCb1 = new NpcCombat(this);
        if (currentHP <= 0) {
            requestAnim(npcCb1.getDeathAnim(), 0);
            currentHP = 0;
            deathDelay = 8;
            isDead = true;
        }
        if (!hit2UpdateReq) {
            hitDiff2 = damage;
            posionHit2 = posion;
            hit2UpdateReq = true;
        } else {
            hitDiff1 = damage;
            posionHit1 = posion;
            hit1UpdateReq = true;
        }
        updateReq = true;
    }

    public int getDeathDelay1() {
        switch (npcType) {
            case 1472:
                return 4;

            case 2745:
                return 6;
            case 5666:
                return 10;

            case 6247:
                return 4;

            case 6625:
                return 2;

            case 6729:
                return 4;

            case 1158:
                return 16;

            case 1160:
                return 6;

            default:
                return 3;
        }
    }

    int getCombatCheck() {
        switch (npcType) {
            case 6729:
                return 121;

            case 6625:
                return 102;

            case 6998:
            case 6999:
                return 136;

            case 1153:
            case 1156:
                return 40;

            case 1154:
                return 100;

            default:
                return 2;
        }
    }

    public int getNoclipPositions() {
        switch (npcType) {

            case 1153:
                return 1;
            case 1154:
                return 1;
            case 1155:
                return 2;
            case 1156:
                return 1;
            case 1157:
                return 2;
            case 1158:
                return 3;
            case 1160:
                return 3;

            default:
                return 0;
        }
    }

    int getCurrentNpcHP() {
        switch (npcType) {

            case 6691:
                return 100;

            case 6625:
                return 44;

            case 6729:
                return 52;

            default:
                return 0;
        }
    }

    int getDistance() {
        switch (npcType) {

            case 5417:
                return 15;
            case 5420:
                return 15;
            case 5421:
                return 15;
            case 50:
                return 18;
            case 2745:
                return 12;
            case 1155:
                return 5;
            case 1157:
                return 6;
            case 1158:
                return 9;
            case 1160:
                return 8;
            case 6222:
                return 6;
            case 6223:
                return 7;
            case 6225:
                return 8;
            case 6227:
                return 8;
            case 6204:
                return 7;
            case 6206:
                return 5;
            case 6208:
                return 8;
            case 5666:
                return 5;
            case 2734:
            case 2735:
            case 2736:
            case 2737:
            case 2738:
            case 2739:
            case 2740:
            case 2741:
            case 2742:
            case 2743:
            case 2744:
                return 13;
            case 2746:
                return 15;
            case 6203:
                return 10;
            case 6248:
                return 20;
            case 6250:
                return 20;
            case 6252:
                return 20;
            case 6260:
                return 20;
            case 6261:
                return 20;
            case 6263:
                return 20;
            case 6265:
                return 20;
            case 5902:
                return 7;
            case 6247:
                return 18;
            case 6625:
                return 13;
            case 6691:
                return 10;
            case 6729:
                return 12;
            case 6998:
                return 12;
            case 6999:
                return 11;

            default:
                return 3;
        }
    }

    public boolean inHomeArea() {
        return absX >= 2494 && absX <= 2521 && absY >= 3482 && absY <= 3875;
    }

    public static final int[] CONSTANTS = {
            2842, 2841, 2840, 2839, 2838, 2837, 2836, 2835, 2834, 2833, 2832, 2831, 2830,
            2829, 2828, 2827, 2826, 2825, 2824
    };
}